package fachada;

import excecoes.ObjetoInexistenteException;
import excecoes.ObjetoInvalidoException;
import excecoes.ObjetoJaExistenteException;
import excecoes.RepositorioException;
import excecoes.SituacaoException;
import guiasaude.Especialidade;
import guiasaude.Hospital;
import guiasaude.PostoSaude;
import guiasaude.UnidadeSaude;
import guiasaude.reps.IRepositorioEspecialidade;
import guiasaude.reps.IRepositorioUnidadeSaude;
import guiasaude.reps.RepositorioEspecialidadeArray;
import queixa.Queixa;
import queixa.reps.IRepositorioQueixa;
import util.FabricaRepositorio;

public class Fachada {

//	private RepositorioQueixaArray repQueixa;
//	private RepositorioUnidadeSaudeArray repUnidadeSaude;
//	private IRepositorioEspecialidade repEspecialidade;
	private IRepositorioQueixa repQueixa;
	private IRepositorioUnidadeSaude repUnidadeSaude;
	private IRepositorioEspecialidade repEspecialidade;

	public static final int NORMAL = 0;
	public static final int EXTRA = 1;
	private int situacaoAtualPrefeitura = Fachada.NORMAL;

	public Fachada(String tipoRep) {
		
//		this.repQueixa = new RepositorioQueixaArray();
//		this.repUnidadeSaude = new RepositorioUnidadeSaudeArray();
//		this.repEspecialidade = RepositorioEspecialidadeLista.getInstance();
		
		// Utilizando o Padrao Factory
		this.repQueixa = (IRepositorioQueixa) FabricaRepositorio.getTipoRep("queixa.reps", "Queixa", tipoRep);
		this.repUnidadeSaude = (IRepositorioUnidadeSaude) FabricaRepositorio.getTipoRep("guiasaude.reps", "UnidadeSaude", tipoRep);
		this.repEspecialidade = (IRepositorioEspecialidade) FabricaRepositorio.getTipoRep("guiasaude.reps", "Especialidade", tipoRep);
	}

	public Queixa consultarQueixa(int codigo) throws RepositorioException,
			ObjetoInexistenteException {
		Queixa q = null;
		q = this.repQueixa.procura(codigo);
		return q;
	}

	public void fecharQueixa(Queixa queixa, String coment)
			throws RepositorioException, ObjetoInexistenteException,
			ObjetoInvalidoException, SituacaoException {
		queixa.fechar(coment);
		this.repQueixa.atualiza(queixa);
	}

	public int abrirQueixa(Queixa queixa) throws RepositorioException,ObjetoInvalidoException,
			SituacaoException {
		
		queixa.abrir();
		
		return this.repQueixa.insere(queixa);
	}

	public RepositorioEspecialidadeArray consultaEspecialidadeporUnidadeSaude(
			int codigoUnidadeSaude) throws ObjetoInexistenteException,
			RepositorioException {

		UnidadeSaude us = this.repUnidadeSaude.procura(codigoUnidadeSaude);
		return us.getEspecialidades();
	}

	public IRepositorioUnidadeSaude getUnidades() {
		return repUnidadeSaude;
	}

	public void incluirEspecialidade(Especialidade esp)
			throws RepositorioException, ObjetoJaExistenteException,
			ObjetoInvalidoException {
		this.repEspecialidade.insere(esp);
	}

	public void incluirUnidadeSaude(UnidadeSaude us)
			throws RepositorioException, ObjetoJaExistenteException,
			ObjetoInvalidoException {
		this.repUnidadeSaude.insere(us);
	}

	public Especialidade consultaEspecialidade(int codigo)
			throws RepositorioException, ObjetoInexistenteException {
		return this.repEspecialidade.procura(codigo);
	}

	public UnidadeSaude consultaUnidadeSaude(int codigo)
			throws RepositorioException, ObjetoInexistenteException {
		return this.repUnidadeSaude.procura(codigo);
	}

	public double calcularMediaMedicoPacienteDia(UnidadeSaude unidade) {
		if (unidade instanceof Hospital)
			return ((Hospital) unidade).medicos()
					/ ((Hospital) unidade).numPacientesDia();
		else
			// postosaude
			return ((PostoSaude) unidade).getAtendentes()
					/ ((PostoSaude) unidade).taxaDiaria();
	}

	public int consultaSituacaoQueixas() {

		// dependendo da situacao da prefeitura, o criterio de avaliacao muda
		// se normal, mais de 20% abertas eh ruim, mais de 10 eh regular
		// se extra, mais de 10% abertas eh ruim, mais de 5% eh regular
		if (this.situacaoAtualPrefeitura == Fachada.NORMAL) {
			if ((double) numeroQueixasAbertas() / repQueixa.size() > 0.2) {
				return Queixa.RUIM;
			} else {
				if ((double) numeroQueixasAbertas() / repQueixa.size() > 0.1) {
					return Queixa.REGULAR;
				}
			}
		}
		if (this.situacaoAtualPrefeitura == Fachada.NORMAL) {
			if ((double) numeroQueixasAbertas() / repQueixa.size() > 0.1) {
				return Queixa.RUIM;
			} else {
				if ((double) numeroQueixasAbertas() / repQueixa.size() > 0.05) {
					return Queixa.REGULAR;
				}
			}
		}
		return Queixa.OTIMO;
	}

	/**
	 * metodo auxiliar para retornar o numero de queixas em aberto no sistema
	 * 
	 * @return
	 */
	private double numeroQueixasAbertas() {
		int contador = 0;
		for (int i = 0; i < repQueixa.size(); i++) {
			if (repQueixa.getElemento(i).getSituacao() == Queixa.ABERTA)
				contador++;
		}

		return contador;
	}
}
